package com.blog.cmrpersonalblog.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaCheckRole;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.blog.cmrpersonalblog.common.Result;
import com.blog.cmrpersonalblog.dto.article.request.ArticleAuditRequest;
import com.blog.cmrpersonalblog.dto.article.request.ArticleBatchOperationRequest;
import com.blog.cmrpersonalblog.dto.article.request.ArticleQueryRequest;
import com.blog.cmrpersonalblog.dto.article.response.ArticleDetailResponse;
import com.blog.cmrpersonalblog.dto.article.response.ArticleManagementResponse;
import com.blog.cmrpersonalblog.dto.markdown.requset.MarkdownPreviewRequest;
import com.blog.cmrpersonalblog.dto.markdown.respnose.MarkdownPreviewResponse;
import com.blog.cmrpersonalblog.service.ArticleManagementService;
import com.blog.cmrpersonalblog.service.MarkdownService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import java.util.List;
import java.util.Map;

/**
 * 文章管理控制器
 * 提供文章的管理功能，包括列表查询、审核、批量操作等
 */
@Slf4j
@RestController
@RequestMapping("/admin/articles")
@CrossOrigin(origins = "*", maxAge = 3600)
@SaCheckRole("admin")
@Validated
public class ArticleManagementController {

   @Resource
    private ArticleManagementService articleManagementService;

   @Resource
    private MarkdownService markdownService;

    /**
     * 分页查询文章列表
     *
     * 支持的排序字段：
     * - id: 文章主键ID
     * - create_time: 创建时间（默认）
     * - update_time: 更新时间
     * - publish_time: 发布时间
     * - view_count: 浏览量
     * - like_count: 点赞数
     *
     * 排序方向：asc（升序）、desc（降序，默认）
     * 注意：为确保分页结果的稳定性，系统会自动添加主键ID作为二级排序
     */
    @GetMapping("/list")
    public Result<IPage<ArticleManagementResponse>> getArticleList(ArticleQueryRequest queryRequest) {
        log.info("管理员查询文章列表: {}", queryRequest);
        try {
            IPage<ArticleManagementResponse> pageResult = articleManagementService.getArticleList(queryRequest);
            return Result.success(pageResult);
        } catch (Exception e) {
            log.error("查询文章列表失败", e);
            return Result.error("查询文章列表失败：" + e.getMessage());
        }
    }

    /**
     * 获取文章详情
     */
    @GetMapping("/{articleId}")
    public Result<ArticleDetailResponse> getArticleDetail(@PathVariable @NotNull Long articleId) {
        log.info("管理员查看文章详情: articleId={}", articleId);
        try {
            ArticleDetailResponse detail = articleManagementService.getArticleDetail(articleId);
            if (detail == null) {
                return Result.error("文章不存在");
            }
            return Result.success(detail);
        } catch (Exception e) {
            log.error("获取文章详情失败", e);
            return Result.error("获取文章详情失败：" + e.getMessage());
        }
    }

    /**
     * 审核文章
     */
    @PostMapping("/audit")
    public Result<Void> auditArticle(@RequestBody @Valid ArticleAuditRequest auditRequest) {
        Long auditorId = StpUtil.getLoginIdAsLong();
        log.info("管理员审核文章: request={}, auditorId={}", auditRequest, auditorId);
        
        try {
            boolean success = articleManagementService.auditArticle(auditRequest, auditorId);
            if (success) {
                return Result.success("审核成功");
            } else {
                return Result.error("审核失败");
            }
        } catch (Exception e) {
            log.error("审核文章失败", e);
            return Result.error("审核失败：" + e.getMessage());
        }
    }

    /**
     * 批量操作文章
     */
    @PostMapping("/batch")
    public Result<Map<String, Object>> batchOperateArticles(@RequestBody @Valid ArticleBatchOperationRequest batchRequest) {
        Long operatorId = StpUtil.getLoginIdAsLong();
        log.info("管理员批量操作文章: request={}, operatorId={}", batchRequest, operatorId);
        
        try {
            Map<String, Object> result = articleManagementService.batchOperateArticles(batchRequest, operatorId);
            return Result.success("批量操作完成", result);
        } catch (Exception e) {
            log.error("批量操作文章失败", e);
            return Result.error("批量操作失败：" + e.getMessage());
        }
    }

    /**
     * 发布文章
     */
    @PostMapping("/{articleId}/publish")
    public Result<Void> publishArticle(@PathVariable @NotNull Long articleId) {
        Long operatorId = StpUtil.getLoginIdAsLong();
        log.info("管理员发布文章: articleId={}, operatorId={}", articleId, operatorId);
        
        try {
            boolean success = articleManagementService.publishArticle(articleId, operatorId);
            if (success) {
                return Result.success("文章发布成功");
            } else {
                return Result.error("文章发布失败");
            }
        } catch (Exception e) {
            log.error("发布文章失败", e);
            return Result.error("发布失败：" + e.getMessage());
        }
    }

    /**
     * 下架文章
     */
    @PostMapping("/{articleId}/unpublish")
    public Result<Void> unpublishArticle(@PathVariable @NotNull Long articleId, 
                                        @RequestParam(required = false) String reason) {
        Long operatorId = StpUtil.getLoginIdAsLong();
        log.info("管理员下架文章: articleId={}, reason={}, operatorId={}", articleId, reason, operatorId);
        
        try {
            boolean success = articleManagementService.unpublishArticle(articleId, operatorId, reason);
            if (success) {
                return Result.success("文章下架成功");
            } else {
                return Result.error("文章下架失败");
            }
        } catch (Exception e) {
            log.error("下架文章失败", e);
            return Result.error("下架失败：" + e.getMessage());
        }
    }

    /**
     * 置顶/取消置顶文章
     */
    @PostMapping("/{articleId}/top")
    public Result<Void> topArticle(@PathVariable @NotNull Long articleId, 
                                  @RequestParam boolean isTop) {
        Long operatorId = StpUtil.getLoginIdAsLong();
        log.info("管理员置顶操作: articleId={}, isTop={}, operatorId={}", articleId, isTop, operatorId);
        
        try {
            boolean success = articleManagementService.topArticle(articleId, isTop, operatorId);
            if (success) {
                return Result.success(isTop ? "文章置顶成功" : "取消置顶成功");
            } else {
                return Result.error("操作失败");
            }
        } catch (Exception e) {
            log.error("置顶操作失败", e);
            return Result.error("操作失败：" + e.getMessage());
        }
    }

    /**
     * 删除文章
     */
    @DeleteMapping("/{articleId}")
    public Result<Void> deleteArticle(@PathVariable @NotNull Long articleId) {
        Long operatorId = StpUtil.getLoginIdAsLong();
        log.info("管理员删除文章: articleId={}, operatorId={}", articleId, operatorId);
        
        try {
            boolean success = articleManagementService.deleteArticle(articleId, operatorId);
            if (success) {
                return Result.success("文章删除成功");
            } else {
                return Result.error("文章删除失败");
            }
        } catch (Exception e) {
            log.error("删除文章失败", e);
            return Result.error("删除失败：" + e.getMessage());
        }
    }

    /**
     * 恢复文章
     */
    @PostMapping("/{articleId}/restore")
    public Result<Void> restoreArticle(@PathVariable @NotNull Long articleId) {
        Long operatorId = StpUtil.getLoginIdAsLong();
        log.info("管理员恢复文章: articleId={}, operatorId={}", articleId, operatorId);
        
        try {
            boolean success = articleManagementService.restoreArticle(articleId, operatorId);
            if (success) {
                return Result.success("文章恢复成功");
            } else {
                return Result.error("文章恢复失败");
            }
        } catch (Exception e) {
            log.error("恢复文章失败", e);
            return Result.error("恢复失败：" + e.getMessage());
        }
    }

    /**
     * 获取文章统计信息
     */
    @GetMapping("/statistics")
    public Result<Map<String, Object>> getArticleStatistics() {
        log.info("管理员查看文章统计信息");
        try {
            Map<String, Object> statistics = articleManagementService.getArticleStatistics();
            return Result.success(statistics);
        } catch (Exception e) {
            log.error("获取文章统计信息失败", e);
            return Result.error("获取统计信息失败：" + e.getMessage());
        }
    }

    /**
     * 获取待审核文章数量
     */
    @GetMapping("/pending-audit-count")
    public Result<Long> getPendingAuditCount() {
        try {
            Long count = articleManagementService.getPendingAuditCount();
            return Result.success(count);
        } catch (Exception e) {
            log.error("获取待审核文章数量失败", e);
            return Result.error("获取数量失败：" + e.getMessage());
        }
    }

    /**
     * 获取文章状态分布
     */
    @GetMapping("/status-distribution")
    public Result<Map<String, Long>> getArticleStatusDistribution() {
        log.info("管理员查看文章状态分布");
        try {
            Map<String, Long> distribution = articleManagementService.getArticleStatusDistribution();
            return Result.success(distribution);
        } catch (Exception e) {
            log.error("获取文章状态分布失败", e);
            return Result.error("获取状态分布失败：" + e.getMessage());
        }
    }

    /**
     * 获取热门文章列表
     */
    @GetMapping("/popular")
    public Result<List<ArticleManagementResponse>> getPopularArticles(@RequestParam(defaultValue = "10") Integer limit) {
        log.info("管理员查看热门文章: limit={}", limit);
        try {
            List<ArticleManagementResponse> articles = articleManagementService.getPopularArticles(limit);
            return Result.success(articles);
        } catch (Exception e) {
            log.error("获取热门文章失败", e);
            return Result.error("获取热门文章失败：" + e.getMessage());
        }
    }

    /**
     * 获取最新文章列表
     */
    @GetMapping("/latest")
    public Result<List<ArticleManagementResponse>> getLatestArticles(@RequestParam(defaultValue = "10") Integer limit) {
        log.info("管理员查看最新文章: limit={}", limit);
        try {
            List<ArticleManagementResponse> articles = articleManagementService.getLatestArticles(limit);
            return Result.success(articles);
        } catch (Exception e) {
            log.error("获取最新文章失败", e);
            return Result.error("获取最新文章失败：" + e.getMessage());
        }
    }

    /**
     * 搜索文章
     */
    @GetMapping("/search")
    public Result<IPage<ArticleManagementResponse>> searchArticles(
            @RequestParam String keyword,
            @RequestParam(defaultValue = "1") Long current,
            @RequestParam(defaultValue = "10") Long size) {
        log.info("管理员搜索文章: keyword={}, current={}, size={}", keyword, current, size);
        try {
            IPage<ArticleManagementResponse> pageResult = articleManagementService.searchArticles(keyword, current, size);
            return Result.success(pageResult);
        } catch (Exception e) {
            log.error("搜索文章失败", e);
            return Result.error("搜索失败：" + e.getMessage());
        }
    }

    /**
     * 获取用户文章列表
     */
    @GetMapping("/user/{userId}")
    public Result<IPage<ArticleManagementResponse>> getUserArticles(
            @PathVariable @NotNull Long userId,
            @RequestParam(defaultValue = "1") Long current,
            @RequestParam(defaultValue = "10") Long size) {
        log.info("管理员查看用户文章: userId={}, current={}, size={}", userId, current, size);
        try {
            IPage<ArticleManagementResponse> pageResult = articleManagementService.getUserArticles(userId, current, size);
            return Result.success(pageResult);
        } catch (Exception e) {
            log.error("获取用户文章失败", e);
            return Result.error("获取用户文章失败：" + e.getMessage());
        }
    }

    /**
     * 获取分类文章列表
     */
    @GetMapping("/category/{categoryId}")
    public Result<IPage<ArticleManagementResponse>> getCategoryArticles(
            @PathVariable @NotNull Long categoryId,
            @RequestParam(defaultValue = "1") Long current,
            @RequestParam(defaultValue = "10") Long size) {
        log.info("管理员查看分类文章: categoryId={}, current={}, size={}", categoryId, current, size);
        try {
            IPage<ArticleManagementResponse> pageResult = articleManagementService.getCategoryArticles(categoryId, current, size);
            return Result.success(pageResult);
        } catch (Exception e) {
            log.error("获取分类文章失败", e);
            return Result.error("获取分类文章失败：" + e.getMessage());
        }
    }

    /**
     * Markdown预览
     */
    @PostMapping("/markdown/preview")
    @SaCheckLogin  // 降低权限要求，登录用户即可使用
    public Result<MarkdownPreviewResponse> previewMarkdown(@RequestBody @Valid MarkdownPreviewRequest request) {
        log.info("Markdown预览请求: contentLength={}", request.getContent().length());
        try {
            MarkdownPreviewResponse response = markdownService.preview(request);
            return Result.success(response);
        } catch (Exception e) {
            log.error("Markdown预览失败", e);
            return Result.error("预览失败：" + e.getMessage());
        }
    }

    /**
     * 重新计算文章统计数据
     */
    @PostMapping("/{articleId}/recalculate-stats")
    public Result<Void> recalculateArticleStats(@PathVariable @NotNull Long articleId) {
        Long operatorId = StpUtil.getLoginIdAsLong();
        log.info("管理员重新计算文章统计: articleId={}, operatorId={}", articleId, operatorId);
        
        try {
            boolean success = articleManagementService.recalculateArticleStats(articleId);
            if (success) {
                return Result.success("统计数据重新计算成功");
            } else {
                return Result.error("统计数据重新计算失败");
            }
        } catch (Exception e) {
            log.error("重新计算文章统计失败", e);
            return Result.error("重新计算失败：" + e.getMessage());
        }
    }
}
